#include <iostream>
#include <vector>
using namespace std;

namespace {

template<typename T>
struct my_is_void {
    static const bool value = false;
};

template<>
struct my_is_void<void> {
    static const bool value = true;
};

template<typename T>
struct my_is_pointer {
    static const bool value = false;
};

template<typename T>
struct my_is_pointer<T*> {
    static const bool value = true;
};

// 一般class和typename用作模板没有区别
// 但希望通知编译器一个名字表示类型时，必须使用关键字 typename，而不能使用 class
template<typename T>
typename T::value_type top(const T &c) {
    if (!c.empty())
        return c.back();
    else
        return typename T::value_type();
}

template<class IterT>
struct my_iterator_traits {
    // 将迭代器的value_type 通过 typedef 为 value_type
    typedef typename IterT::value_type value_type;
};

template<class IterT>
struct my_iterator_traits<IterT*> {
    typedef IterT value_type;
};

void fun(int a) {
    cout << "fun(int) is called " << endl;
}

void fun(double a) {
    cout << "fun(double) is called " << endl;
}

void fun(char a) {
    cout << "fun(char) is called " << endl;
}

void Handle() {
    my_is_void<bool> t1;
    cout << "t1.value = " << t1.value << endl;

    my_is_void<void> t2;
    cout << "t2.value = " << t2.value << endl;

    my_is_pointer<int> p1;
    cout << "p1.value = " << p1.value << endl;

    my_is_pointer<int*> p2;
    cout << "p2.value = " << p2.value << endl;

    vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    cout << "top vec " << top<vector<int> >(vec) << endl;  // 输出3

    // 使用vector迭代器的类型作为a值类型
    my_iterator_traits<vector<int>::iterator>::value_type a;
    fun(a);  // 输出 fun(int) is called
    my_iterator_traits<vector<double>::iterator>::value_type b;
    fun(b);  // 输出 fun(double) is called
    my_iterator_traits<char*>::value_type c;
    fun(c);  // 输出 fun(char) is called
}

}

void HandleTraits() {
    Handle();
}
